<!DOCTYPE html>
<html lang="en">
<head>
    <title>webchart--时序图</title>
    <meta charset='utf-8'>
    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="Keywords" content="在线时序图, 在线流程图, webchart, webflow, 免费在线作图工具, 代码作图, 代码绘制, 时序图, 流程图, 代码绘制流程图, 代码绘制时序图">
    <meta name="description" content="webchart提供免费在线制作时序图,流程图,使用简单的描述代码绘制图形,方便快捷,易于修改、分享" />
    <link href="css/style2.css" rel="stylesheet"/>
    <link rel="stylesheet" type="text/css" href="css/sequence-diagram-min.css" media="screen" />
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>    
    <script src="https://cdn.bootcss.com/webfont/1.6.6/webfontloader.js"></script>
    <script src="https://cdn.bootcss.com/snap.svg/0.5.1/snap.svg-min.js"></script>
    <script src="https://cdn.bootcss.com/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://cdn.bootcss.com/ace/1.2.6/ace.js"></script>
    <script src="jslib/svginnerhtml.min.js"></script>
    <script src="jslib/sequence-diagram-min.js"></script>
    <style>
        .add-new{
            width: 100px;
            text-align: center;
        }
    </style>
    <script>
        //百度统计
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?67f6150b658f95cafa054cd39a24c1ae";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>

<body>
    <div id="main">
    	<div class="logo">
            <div class="logo-img">
             
                {{/*<img src="./logo.png" alt="">*/}}
            </div>
            <div class="page-router-warp">
                <a class="active" href="index.html">时序图</a>
                <a href="flow.html">流程图</a>
            </div>
            <div class="add-new">
                <span id="addBtn">新建</span>
            </div>
    	</div>
        <div id="demo" class="index-page-warp">
            <div class="left-code-warp">
                <div class="toolbar">
                    <div class="left">
                        主题:
                        <select class="theme">
                            <option value="simple" selected>默认</option>
                            <option value="hand">手绘</option>
                        </select>
                    </div>
                    <div class="right">
                        <a href="#" class="download">下载SVG</a>
                        | <a href="#" id="downloadJpeg">下载JPG</a>
                        | <a href="#" id="downloadPng">下载PNG</a>
                        | <a href="#" class="case">示例</a>
                        | <a href="https://bramp.github.io/js-sequence-diagrams" target="_blank">帮助</a>
                    </div>
                </div>
                <div class="editor-wrapper">
                    <div class="editor"># #开头的为是注释
#participant 对象名称: 定义一个对象, 按顺序排列
#participant 可以不写. 指向时会自动生成
participant 测试对象

# 标题 这里 title 不区分大小写
Title : 标题名称

# 添加步奏
对象1 -> 对象2: 操作说明
对象2 -> 对象3: 操作说明 \n 操作说明
对象1 -> 对象3: 夸对象指向

# 四种箭头指向
对象1 -> 对象2: 实线实心
对象1 --> 对象2: 虚线实心
对象1 ->> 对象2: 实线虚心
对象1 -->> 对象2: 虚线虚心

# 添加说明
# note left of [对象名称] : [说明]
# note rigth of [对象名称] : [说明]
# note over [对象名称] : [说明]
# note over [对象名称,对象名称] : [说明]
note left of 测试对象: 测试对象左侧添加说明
note right of 测试对象: 测试对象右侧添加说明
note over 测试对象: 测试对象中间添加说明
note over 测试对象,对象2: 两个对象中间添加说明
note over 测试对象,对象3: 两个对象中间添加说明</div>
                </div>
            </div>
            <div class="right-pic-warp">
                <div class="diagram">This should be a diagram! If you don't see it you need Javascript enabled</div>
            </div>
            <div class="data-list-warp">
                <div class="input-name-warp">
                    <input id="nameTxt" type="text" placeholder="输入名称">
                    <div id="submitName" class="submit-name">确定</div>
                    <div id="submitCancel" class="submit-name">取消</div>
                </div>
                <div class="list-box" id="listBox">

                </div>
            </div>
        </div>
    </div>
<script>
    let copyKey = true;
    $(function() {
        let code_default=`# #开头的为是注释
#participant 对象名称: 定义一个对象, 按顺序排列
#participant 可以不写. 指向时会自动生成
participant 测试对象

# 标题 这里 title 不区分大小写
Title : 标题名称

# 添加步奏
对象1 -> 对象2: 操作说明
对象2 -> 对象3: 操作说明 \\n 操作说明
对象1 -> 对象3: 夸对象指向

# 四种箭头指向
对象1 -> 对象2: 实线实心
对象1 --> 对象2: 虚线实心
对象1 ->> 对象2: 实线虚心
对象1 -->> 对象2: 虚线虚心

# 添加说明
# note left of [对象名称] : [说明]
# note rigth of [对象名称] : [说明]
# note over [对象名称] : [说明]
# note over [对象名称,对象名称] : [说明]
note left of 测试对象: 测试对象左侧添加说明
note right of 测试对象: 测试对象右侧添加说明
note over 测试对象: 测试对象中间添加说明
note over 测试对象,对象2: 两个对象中间添加说明
note over 测试对象,对象3: 两个对象中间添加说明`;

        if(!localStorage.getItem("now_item")){
            localStorage.setItem("now_item", "code_seq")
        }

        
        function setup_editor(div) {

            var editor_div = div.find(".editor");
            var diagram_div = div.find(".diagram");
            var theme_div = div.find(".theme");
            var download_link = div.find('.download');
            var download_png = div.find('#downloadPng');
            var download_jpeg = div.find('#downloadJpeg');

            // Setup the editor diagram
            var editor = ace.edit(editor_div.get(0));
            editor.$blockScrolling = Infinity;
            editor.setTheme("ace/theme/crimson_editor");
            editor.getSession().setMode("ace/mode/asciidoc");
            editor.getSession().on('change', _.debounce(on_change, 100));
            loadData(editor);
            $('.case').click({editor:editor},resetData);
            download_link.unbind('click');
            download_png.unbind('click');
            download_jpeg.unbind('click');
            //下载 svg 图片
            download_link.click(function(ev) {
                var svg = diagram_div.find('svg')[0];
                var width = parseInt(svg.width.baseVal.value);
                var height = parseInt(svg.height.baseVal.value);
                var data = editor.getValue();
                var xml = '<?xml version="1.0" encoding="utf-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" width="' +
                    width + '" height="' + height +
                    '" xmlns:xlink="http://www.w3.org/1999/xlink"><source><![CDATA[' + data + ']]></source>' +
                    svg.innerHTML + '</svg>';

                var a = $(this);
                a.attr("download", localStorage.getItem("now_item") + ".svg"); // TODO I could put title here
                a.attr("href", "data:image/svg+xml," + encodeURIComponent(xml));
            });
            //下载 png 图片
            download_png.click(function (ev) {
                var svg = diagram_div.find('svg')[0];
                var width = parseInt(svg.width.baseVal.value);
                var height = parseInt(svg.height.baseVal.value);
                var data = editor.getValue();
                var xml = '<?xml version="1.0" encoding="utf-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" width="' +
                    width + '" height="' + height +
                    '" xmlns:xlink="http://www.w3.org/1999/xlink"><source><![CDATA[' + data + ']]></source>' +
                    svg.innerHTML + '</svg>';

                let src = "data:image/svg+xml," + encodeURIComponent(xml);
                const img = new Image(); // 创建图片容器承载过渡
                img.src = src;
                img.onload = function() {
                    const canvas = document.createElement('canvas');
                    canvas.width = img.width;
                    canvas.height = img.height;
                    const context = canvas.getContext('2d');
                    context.drawImage(img, 0, 0);

                    let a = document.createElement("a");
                    a.download = localStorage.getItem("now_item") + ".png";
                    a.href = canvas.toDataURL('image/png');
                    a.click();
                };

            });
            //下载 JPEG 图片
            download_jpeg.click(function (ev) {
                var svg = diagram_div.find('svg')[0];
                var width = parseInt(svg.width.baseVal.value);
                var height = parseInt(svg.height.baseVal.value);
                var data = editor.getValue();
                var xml = '<?xml version="1.0" encoding="utf-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" width="' +
                    width + '" height="' + height +
                    '" xmlns:xlink="http://www.w3.org/1999/xlink"><source><![CDATA[' + data + ']]></source>' +
                    svg.innerHTML + '</svg>';

                let src = "data:image/svg+xml," + encodeURIComponent(xml);
                const img = new Image(); // 创建图片容器承载过渡
                img.src = src;
                img.onload = function() {
                    const canvas = document.createElement('canvas');
                    canvas.width = img.width;
                    canvas.height = img.height;
                    const context = canvas.getContext('2d');
                    context.fillStyle="#ffffff"
                    context.fillRect(0, 0, canvas.width, canvas.height);
                    context.drawImage(img, 0, 0);

                    let a = document.createElement("a");
                    a.download = localStorage.getItem("now_item") + ".jpg";
                    a.href = canvas.toDataURL('image/jpeg');
                    a.click();
                };

            });

            theme_div.change(on_change);
            on_change();

            function on_change() {
                try {
                    var diagram = Diagram.parse(editor.getValue());
                    editor.getSession().setAnnotations([]);
                    saveData(editor);

                    // Clear out old diagram
                    diagram_div.html('');

                    var options = {
                        theme: theme_div.val(),
                        scale: 1
                    };

                    // Draw
                    diagram.drawSVG(diagram_div.get(0), options);
                } catch (err) {
                    var annotation = {
                        type: "error", // also warning and information
                        column: 0,
                        row: 0,
                        text: err.message
                    };
                    if (err instanceof Diagram.ParseError) {
                        annotation.row = err.loc.first_line - 1;
                        annotation.column = err.loc.first_column;
                    }
                    editor.getSession().setAnnotations([annotation]);
                    throw err;
                }
            }
        }
        setup_editor($('#demo'));
        function loadData (editor){
            var data =localStorage.getItem('code_seq');
            if(data && data!==''){
                editor.setValue(data);
                editor.gotoLine(1);
            }
        }
        //自动保存数据
        function saveData (editor){
            var code = editor.getValue();
            if( code!=='' && code!==code_default){
                localStorage.setItem('code_seq',code);
                if(!localStorage.getItem("data_arr")){
                    localStorage.setItem("data_arr", "新建时序图");
                    localStorage.setItem("now_item", "新建时序图");
                    showNavList()
                }
                if(copyKey){
                    localStorage.setItem(localStorage.getItem("now_item"), code);
                }
            }
        }

        //示例点击
        function resetData (event){
            copyKey = false;
            $(".item").removeClass("actives");
            var init_default =event.data.editor.getValue();
            if(init_default !== code_default){
                event.data.editor.setValue(code_default);
                event.data.editor.gotoLine(1);
            }
        }

        /*-------------------*/


        //展示数据
        showNavList();
        //新建按钮点击
        $("#addBtn").click(function () {
            $(".input-name-warp").show()
        });
        //新建取消
        $("#submitCancel").click(function () {
            $(".input-name-warp").hide()
            $("#nameTxt").val("")
        });
        //新建提交
        $("#submitName").click(creatNewData);
        //创建新标签
        function creatNewData(){
            let v = $("#nameTxt").val().trim();
            if(v === ""){
                alert("名称不能为空")
                return
            }
            if(v.indexOf(",")>0){
                alert("名称里不能包含 , 等特殊符号")
                return
            }
            console.log($("#nameTxt").val())
            let l = localStorage.getItem("data_arr")?localStorage.getItem("data_arr"):"";
            if(l.trim() !== ""){
                let arr = l.split(",");
                for(let i = 0; i<arr.length; i++){
                    if(arr[i] === v){
                        alert("名称重复");
                        return
                    }
                }
            }

            if(l === ""){
                window.localStorage.setItem("data_arr", v)
            }else {
                window.localStorage.setItem("data_arr", v + "," + l)
            }
            $(".input-name-warp").hide();

            localStorage.setItem(v, "#"+v);
            if(!localStorage.getItem("code_seq")){
                localStorage.setItem("code_seq", "#案例");
            }

            localStorage.setItem("now_item", v);
            localStorage.setItem("code_seq", localStorage.getItem(localStorage.getItem("now_item")));
            showNavList()
            setup_editor($('#demo'));
            $("#nameTxt").val("")
        }

        //创建 list 导航 展示数据
        function showNavList(){
            let l = localStorage.getItem("data_arr")?localStorage.getItem("data_arr"):"";
            if(l.trim() === ""){
                return
            }
            let arr = l.split(",");
            $("#listBox").html("");

            let html = "";
            for(let i=0;i<arr.length; i++){
               html += `
                    <div class="item">
                        <p>${arr[i]}</p>
                        <div class="delete-btn">X</div>
                    </div>
                `;
            }
            $("#listBox").append(html)
            
            $(".item").each(function () {
                if($(this).find("p").text() === localStorage.getItem("now_item")){
                    $(this).addClass("actives").siblings().removeClass("actives")
                }
            })
        }

        //删除标签
        $("#listBox").on("click", ".delete-btn", function (event) {
            event.stopPropagation();
            if(confirm("确定要删除这条数据吗?")){
                let l = localStorage.getItem("data_arr")?localStorage.getItem("data_arr"):"";
                if(l.trim() === ""){
                    return
                }
                let arr = l.split(",");
                let num = $(this).parent(".item").index();
                let dItmeName = arr[num];
                localStorage.removeItem(arr[num]);
                arr.splice(num, 1);
                let str = arr.join(",");
                localStorage.setItem("data_arr", str);
                showNavList();
                if(dItmeName === localStorage.getItem("now_item")){
                    alert("当前标签已被删除. 左侧编辑内容不会被保存.请新建一个标签或者切换标签后再编辑")
                }
            }
        });

        //切换标签
        $("#listBox").on("click", ".item", function (event) {
            copyKey=true;
            event.stopPropagation();
            localStorage.setItem("now_item", $(this).find("p").text());
            localStorage.setItem("code_seq", localStorage.getItem(localStorage.getItem("now_item")));
            setup_editor($('#demo'));
            $(this).addClass("actives").siblings().removeClass("actives")
        });
    });
</script>
</body>

</html>
